#include "main.h"

#define MAX_APPSOCK_BUFFER_SIZE 1024*1024


char lockfile[500];
//int lfp;
int pid, sid;

void signal_handler(int sig) {
	switch(sig) {
	case SIGHUP:
		break;
	case SIGTERM:
//		close(lfp);
		unlink(lockfile);
		exit(0);
		break;
	}
}


int daemonize() {
	char buf[1000];
	int i;

	trace("Daemonizing...");
	
	if ( (pid=fork()) < 0 )
		fatal("fork()");
		
	if (pid > 0) exit(0);

	umask(0);
        
	/* Open any logs here */        
        
//	sid = setsid();
//	if (sid < 0)
//		exit(1);

//	for (i=getdtablesize();i>=0;--i)
//		close(i);

//	if ((chdir("/")) < 0)
//		exit(1);
//	close(STDIN_FILENO);
//	close(STDOUT_FILENO);
//	close(STDERR_FILENO);


	signal(SIGCHLD,SIG_IGN);
	signal(SIGTSTP,SIG_IGN);
	signal(SIGTTOU,SIG_IGN);
	signal(SIGTTIN,SIG_IGN);
	signal(SIGHUP,signal_handler);
	signal(SIGTERM,signal_handler);
}


void *server(void *param){
	char sockname[500]=APPLICATION_SOCKET;
	register int s, c;
	int i, len;
	long sz;
	char *buf, *b;
	struct sockaddr_un sa;
	struct tm *tm;

	trace("Opening application socket %s", sockname);
	
	if((s=socket(PF_LOCAL, SOCK_STREAM, 0)) < 0)
		fatal("socket()");	
	bzero(&sa, sizeof sa);
	sa.sun_family = AF_UNIX;
	strcpy(sa.sun_path, sockname);
	unlink(sa.sun_path);
	
	if ((bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_un))) == -1){
		close(s);
		fatal("bind()");
	}	
	chmod(sockname, S_IRWXU|S_IRWXG|S_IRWXO);
	listen(s, 5);
	for (;;) {
		trace("*** Waiting application socket...");
		i = sizeof sa;
		c = accept(s, (struct sockaddr *)&sa, (socklen_t *)&i);
		trace("ACCEPT");
		b = buf = (char *)malloc(MAX_APPSOCK_BUFFER_SIZE);
		sz=0;
		while(len=recv(c, b, 10000,0)){
			if((sz+=len)+10000>MAX_APPSOCK_BUFFER_SIZE)
				fatal("Buffer overflow. Maximum buffer size is %i", MAX_APPSOCK_BUFFER_SIZE);
			*(b+=len)=0;
			if(strcmp(b-4,"###\n")==0){
				*(b-4)=0;
				break;
			}
		}
		trace("Data recieved. Evaluating javascript");
		eval(buf, NULL, 0);
		trace("Evaluated! Freeing buf");
		free(buf);
		sprintf(buf, "OK\n");
		//send(c, buf, strlen(buf), 0);
		close(c);
	}
}



char **cmd_argv;
int cmd_argc;


int restart_timeout=2000;
int opt_daemonize=0;

/*
int jshost(int argc, char *argv[]) {
	trace("Starting jshost. argc=%i", argc);

	if(argc==1){
		js_init();
		server(APPLICATION_SOCKET);
		js_done(0);
	}

	if(argc==2)
		client(APPLICATION_SOCKET, argc, argv);

	trace("Exiting jshost");
	exit(0);
}
*/

int lfp;


main(int argc, char **argv) {
	pid_t pid;
	int status;
	int opt;
	char buf[1000];

	cmd_argc = argc;
	cmd_argv = argv;

	while ((opt = getopt(argc, argv, "sqhdt:")) != -1) {
		switch (opt) {
			case 'h':
				fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n", argv[0]);
				exit(1);
			case 'd':
				opt_daemonize=1;
				break;
			case 't':
				restart_timeout=atoi(optarg);
				break;
		}
	}


//	if (argc>=2) {
//		eval_file(argv[1]);
//		exit(0);
//	}
	
	if ((lfp=open(LOCKFILE,  O_RDWR|O_CREAT, 0640))<0)
		fatal("Cannot create lock file");

	if (lockf(lfp,F_TLOCK,0)<0)
		fatal("Already started");
		//exit(client(argc, argv));

	sprintf(buf, "%d\n", getpid());
	write(lfp, buf, strlen(buf));

	
	trace("Starting server...");
	
	if (opt_daemonize)
		daemonize();

/*	
	pthread_t tid;
	if(pthread_create(&tid, NULL, server, NULL)<>0)
		fatal("main: pthread_create()");
*/
		
	while (1) {
		trace("Superloop");
		trace("Starting new child process");

		if ((pid=fork())<0)
			fatal("fork");
			
		if (pid==0) {
			trace("before server()");
			server(NULL);
			trace("after server()");
			exit(1);
		}	
		
		trace("Child server started with PID %i", pid);
		waitpid(pid, &status, 0);
		trace("Child server exited. Waiting 5 sec...");
		sleep(5);
		trace("Restarting");
	}
	
	exit(0);
}







